//
//  AudioPlayer.m
//  LO_MUSIC
//
//  Created by 向祖华 on 16/2/26.
//  Copyright © 2016年 杨少锋. All rights reserved.
//

#import "AudioPlayer.h"
#import <AVFoundation/AVFoundation.h>
//单例
static AudioPlayer * audioPlayer = nil;

//私有属性
@interface AudioPlayer()

//播放器
@property(nonatomic,strong)AVPlayer * localPlayer;
//记录当前的播放/暂停状态
@property(nonatomic,assign,getter=isCurrentPlaying)BOOL CurrentPlaying;
//计时器
@property(nonatomic,strong)NSTimer * timer;

@end


@implementation AudioPlayer

//是否正在播放(重写get方法)
-(BOOL)isPlaying
{
    return self.isCurrentPlaying;
}
//1. 文件是单例
+(instancetype)shareAudioPlayer
{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        audioPlayer = [[AudioPlayer alloc]init];
    });
    return audioPlayer;
}
//重写初始化方法
-(instancetype)init
{
    self = [super init];
    if (self) {
        //通知中心添加观察者，当avplayer播放完成，则执行selecter中的方法（用于，一首歌完成要跳到下一首歌）
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playEnd) name:AVPlayerItemDidPlayToEndTimeNotification object:nil];
    }
    return self;
}

//接收到播放结束的通知执行的方法
-(void)playEnd
{
    //播放结束
    if (self.delegate&&[self.delegate respondsToSelector:@selector(playFinish)]) {
        [self.delegate playFinish];
    }
}

//2. 播放
-(void)playWithUrl:(NSString*)url
{
    //移除监听状态
    [self.localPlayer.currentItem removeObserver:self forKeyPath:@"status" context:nil];
    //创建一个被播放对象
    AVPlayerItem * item = [[AVPlayerItem alloc]initWithURL:[NSURL URLWithString:url]];
    //1.监听者 2.监听属性 3.新值 旧值 4.附加信息
    //self监听item的status属性（未知，准备播放，失败）
    [item addObserver:self forKeyPath:@"status" options:(NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld) context:nil];
    //替换播放对象，使刚创建的item为当前要播放的对象
    [self.localPlayer replaceCurrentItemWithPlayerItem:item];
}
//KVO的回调方法，当status的属性有变化时执行
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context
{
    //如果监听的属性不是status，直接返回
    if (![keyPath isEqualToString:@"status"]) {
        return;
    }
    //取出变化的值
    AVPlayerItemStatus value = [change[@"new"]integerValue];
    if (value == AVPlayerItemStatusReadyToPlay) {
        //准备好了
        [self play];
    }else
    {
        //准备失败 准备情况不知道
    }
}

//3. 暂停/恢复
-(void)playOrPause
{
    if (self.isPlaying) {
        //暂停
        [self pause];
    }else
    {
        //播放
        [self play];
    }
}

//自定义播放
-(void)play{
    //计时器释放
    [self.timer invalidate];
    //播放
    [self.localPlayer play];
    self.CurrentPlaying = YES;
    //初始化计时器（为了时进度条跟随变化）
    //repeat yes 每0.1秒执行一次 no只执行一次
    self.timer = [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(timerAction) userInfo:nil repeats:YES];
}
//自定义暂停
-(void)pause
{
    //暂停
    [self.localPlayer pause];
    //将播放状态赋值为NO,即不播放
    self.CurrentPlaying = NO;
    //清空timer
    [self.timer invalidate];
    self.timer = nil;
}


//
-(void)timerAction
{
    //判断如果代理存在且代理方法能响应
    if (self.delegate&&[self.delegate respondsToSelector:@selector(playWithTime:)]) {
        //self.localPlayer.currentTime.value当前第几帧，self.localPlayer.currentTime.timescale每秒多少帧
        CGFloat time = self.localPlayer.currentTime.value*1.0/self.localPlayer.currentTime.timescale;
        [self.delegate playWithTime:time];
    }
}

//4. 停止
-(void)stop
{
    //把时间设置为零
    [self.localPlayer seekToTime:CMTimeMakeWithSeconds(0, self.localPlayer.currentTime.timescale) completionHandler:^(BOOL finished) {
        
        if (finished) {//设置完毕
            
            [self pause];//暂停
            self.CurrentPlaying = NO;

        }
    }];
    
}
//5. 从什么时候开始播放
-(void)seekToWithTime:(CGFloat)time
{
    //先暂停
    [self pause];
    //设置从什么地方开始播放
    [self.localPlayer seekToTime:CMTimeMakeWithSeconds(time, self.localPlayer.currentTime.timescale) completionHandler:^(BOOL finished) {
        if (finished) {
            //播放
            [self play];
        }
    }];
}
//6.获取音量
-(CGFloat)volume
{
    return self.localPlayer.volume;
}
//6.设置音量
-(void)setVolume:(CGFloat)volume
{
    self.localPlayer.volume = volume;
}

#pragma mark - 懒加载

-(AVPlayer *)localPlayer
{
    if (!_localPlayer) {
        _localPlayer = [[AVPlayer alloc]init];
        _localPlayer.volume = 0.5;//初始化音量
    }
    return _localPlayer;
}

@end
